/**   
 * @Title: BeanUtils.java 
 * CopyRight(c)2010-DMX 
 */
package com.dmx.fw.component.util;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaProperty;
import org.apache.commons.beanutils.PropertyUtils;

import com.dmx.fw.constant.ViewConstant;

/** 
 * @Description: Bean Util
 * @author: system
 * @date: 2006
 * @version V1.0 
 * 
 */
public class BeanUtils {
	private static final String CLS="class";
	/**
	 * @Description copy properties,加入了对空值，和空集的处理，对DynaBean中只能是大写或小写的处理(不区分大小写)
	 * @param source: 源
	 * @param target: 目标
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public static Object copyPropertiesByBean(Object source, Object target)throws IllegalAccessException, InvocationTargetException{
        if (target == null) throw new IllegalArgumentException("No destination bean specified");
        if (source == null) throw new IllegalArgumentException("No source bean specified");
        Class clazz = source.getClass();
        if (source instanceof DynaBean) {
        	PropertyDescriptor[] propertyDescriptors=PropertyUtils.getPropertyDescriptors(target.getClass());
        	DynaBean dynaBean=((DynaBean) source);
            for (int i = 0; i < propertyDescriptors.length; i++) {
                String name = propertyDescriptors[i].getName();
                DynaProperty dynaProperty =dynaBean.getDynaClass().getDynaProperty(name);
                if (dynaProperty==null) dynaProperty =dynaBean.getDynaClass().getDynaProperty(name.toLowerCase());
                if (dynaProperty==null) dynaProperty =dynaBean.getDynaClass().getDynaProperty(name.toUpperCase());
                if (dynaProperty!=null) {
                    Object value = dynaBean.get(dynaProperty.getName());
                    org.apache.commons.beanutils.BeanUtils.copyProperty(target, name, value);
                }
            }
        } else if (source instanceof Map) {
            Iterator names = ((Map) source).keySet().iterator();
            while (names.hasNext()) {
                String name = (String) names.next();
                if (PropertyUtils.isWriteable(target, name)) {
                    Object value = ((Map) source).get(name);
                    org.apache.commons.beanutils.BeanUtils.copyProperty(target, name, value);
                }
            }
        }else{
            //PropertyDescriptor origDescriptors[] =PropertyUtils.getPropertyDescriptors(source);
        	PropertyDescriptor[] origDescriptors=PropertyUtils.getPropertyDescriptors(target.getClass());
            for (int i = 0; i < origDescriptors.length; i++) {
                String name = origDescriptors[i].getName();
                if (CLS.equals(name)) continue;
                Object value =null;
                try {
	                value =PropertyUtils.getSimpleProperty(source, name);
	                boolean iscopy=CopyableUtils.isCopyable(name, value, clazz);
	                if (PropertyUtils.isReadable(source, name) &&
	                    PropertyUtils.isWriteable(target, name) && iscopy) {
	                    org.apache.commons.beanutils.BeanUtils.copyProperty(target, name, value);
	                }
                }catch (NoSuchMethodException e) {
                	//System.out.println("source no propertyName="+name+"="+value);
                	//e.printStackTrace();
                        ; // Should not happen
                }
                
            }
        }
        return target;
	}
   public static void copyPropertiesByBeanUtils(Object source, Object target)throws Exception{
	    org.apache.commons.beanutils.BeanUtils.copyProperties(target,source);
   }
   
/**
 * @Description 求beans集合和values集合的补集
 * @param beans: 源对象集合
 * @param propertyName: 目标对象的用于比较的属性名
 * @param values: 是目标对象的用于比较的属性名的值集合
 * @return String[]
 * @throws Exception
 */
    public static String[] complementarSetBeansByStrs(List beans,String propertyName,String[] values)throws Exception{
		if(beans==null) return values;
		Set vals=getArrayToSet(values);
		for(int i=0;i<beans.size();i++){
			Object key=PropertyUtils.getSimpleProperty(beans.get(i),propertyName);
			if(key!=null && vals.contains(key.toString())){
				vals.remove(key.toString());
			}
		}
		return (String[])vals.toArray(new String[0]);
	}
    public static String[] complementarSetBeansByStrs(Collection beans,String propertyName,String[] values)throws Exception{
		if(beans==null) return values;
		Set vals=getArrayToSet(values);
		for(Iterator it=beans.iterator();it.hasNext();){
			Object key=PropertyUtils.getSimpleProperty(it.next(),propertyName);
			if(key!=null && vals.contains(key.toString())){
				vals.remove(key.toString());
			}
		}
		return (String[])vals.toArray(new String[0]);
	}
    
    /**
     * @Description 字符串数组转Set
     * @param values: 字符串数组
     * @return Set
     */
    public static Set getArrayToSet(String[] values){
		 Set temp=new HashSet();
		 if(values!=null && values.length>0) 
		    Collections.addAll(temp, values);
		 return temp;
	}
}

